package pcb.models 
{
	import com.intel.patterns.observer.Subject;
	import com.intel.utils.Debugger;
	import com.intel.utils.QueueLoaderLite;
	import com.intel.utils.QueueLoaderLiteEvent;
	import com.intel.utils.SoundManager;
	import flash.utils.Dictionary;
	import pcb.models.vo.IAsset;
	import pcb.models.vo.NarrativeVo;
	
	/**
	 * The intention is to make this a central repository for all assets used in slides
	 * subclasses of UIComponent that are used as base classes for Flash library components
	 * will have a modellocator property that can reference AssetModel
	 * 
	 * @author Fintan Boyle
	 */
	public class AssetModel extends Subject implements IModel 
	{
		
		//will be referenced in Cmd_loadLessonAssets and Cmd_respondToUserGesture
		public var assetLoader:QueueLoaderLite;
		
		private var soundManager:SoundManager;
		
		private var assets:Dictionary; //id / IAsset  pairs
		private var assetCount:int = 0;
		
		public function AssetModel() 
		{
			soundManager = new SoundManager();
			reset();
			Debugger.traceOut("AssetModel constructed");
		}
		
		public function reset():void 
		{
			soundManager.stopAllSounds();
			
			assets = new Dictionary(true);
			assetCount = 0;
			if(assetLoader) assetLoader.dispose();
			assetLoader = new QueueLoaderLite();
			soundManager.removeAllSounds();
			
			removeListeners();
			
			//assetLoader.addEventListener(QueueLoaderLiteEvent.ITEM_PROGRESS, onItemProgress, false, 0, true);
			assetLoader.addEventListener(QueueLoaderLiteEvent.ITEM_COMPLETE, onItemComplete);
			assetLoader.addEventListener(QueueLoaderLiteEvent.ITEM_ERROR, onItemError);
			assetLoader.addEventListener(QueueLoaderLiteEvent.QUEUE_COMPLETE, onQueueComplete);
			
		}
		
		public function addAsset(id:String, asset:IAsset):void
		{
			Debugger.traceOut("addAsset " + id);
			assets[id] = asset;
			assetCount++;
			addToQueue(asset.getUrl(), id);
		}
		
		private function hasAssets():Boolean
		{
			if (assetCount > 0) return true;
			
			return false;
		}
		
		public function getAssetById(id:String):IAsset {
			
			return assets[id];			
		}
		
		public function addToQueue(url:String, strTitle:String):void {			
			assetLoader.addItem(url, null, {title:strTitle});
		}
		
		public function executeQueue():void {
			assetLoader.execute();
			
			notify(Notifications.ASSET_MODEL_CALLING);
		}
		
		private function onQueueStart(event:QueueLoaderLiteEvent):void {
			Debugger.traceOut(">> "+event.type);
		}
							
		private function onItemStart(event:QueueLoaderLiteEvent):void {
			Debugger.traceOut("\t>> "+event.type+ "item title: "+event.title);
		}
							
		private function onItemProgress(event:QueueLoaderLiteEvent):void {
			Debugger.traceOut("\t>> "+event.type+": "+[" percentage: "+event.percentage]);
		}
							
		private function onQueueProgress(event:QueueLoaderLiteEvent):void {
			Debugger.traceOut("\t>> "+event.type+": "+[" queuepercentage: "+event.queuepercentage]);
		}
		
		
		private function onItemComplete(event:QueueLoaderLiteEvent):void {
			
			Debugger.traceOut("\t>> LOAD COMPLETE name: "+event.type + " event:" + event.type+" - "+["target: "+event.title]+"\n");
			if (event.fileType == QueueLoaderLite.FILE_MP3) {
				
				if(hasAssets()){
					var vo:NarrativeVo = getAssetById(event.title) as NarrativeVo;
					
					soundManager.addExternalSound(event.file, vo.getId());
					
					vo.sound = event.file; //(dispatches ModelEvent.LOADED event)
				}
			}
			
		}

		private function onItemError(event:QueueLoaderLiteEvent):void {
			Debugger.traceOut("\n>>" + event.type + "\n");
			//perhaps..
			//if (event.fileType == QueueLoaderLite.FILE_MP3) vo.sound = null;
		}

		private function onQueueComplete(event:QueueLoaderLiteEvent):void {
			Debugger.traceOut("QUEUE COMPLETE ** " + event.type);
			
			removeListeners();
		}
		
		public function getSoundManager():SoundManager 
		{
			return soundManager;
		}
		
		private function removeListeners():void 
		{
			//assetLoader.removeEventListener(QueueLoaderLiteEvent.ITEM_PROGRESS, onItemProgress, false, 0, true);
			if(assetLoader.hasEventListener(QueueLoaderLiteEvent.ITEM_COMPLETE))assetLoader.removeEventListener(QueueLoaderLiteEvent.ITEM_COMPLETE, onItemComplete);
			if(assetLoader.hasEventListener(QueueLoaderLiteEvent.ITEM_ERROR))assetLoader.removeEventListener(QueueLoaderLiteEvent.ITEM_ERROR, onItemError);
			if(assetLoader.hasEventListener(QueueLoaderLiteEvent.QUEUE_COMPLETE))assetLoader.removeEventListener(QueueLoaderLiteEvent.QUEUE_COMPLETE, onQueueComplete);
			
		}
		
	}
	
}